﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace FDFtpSync.Utils
{
    /*
     * CreatedOn: 2018-05-23
     * CreatedBy: Jackie Lee(天宇遊龍)
     */
    /// <summary>
    /// MD5处理
    /// </summary>
    public static class MD5Helper
    {
        public static string Md5(byte[] buffer)
        {
            var md5 = MD5.Create();
            return BitConverter.ToString(md5.ComputeHash(buffer)).Replace("-", "");
        }
        
        public static string Md5Stream(Stream stream)
        {
            var md5 = MD5.Create();
            md5.ComputeHash(stream);

            var buffer = md5.Hash;
            md5.Clear();
            return BitConverter.ToString(buffer).Replace("-", "");
        }

        //public static string Md5Stream(string fileName)
        //{
        //    using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
        //    {
        //        var md5 = MD5.Create();
        //        md5.ComputeHash(fs);

        //        var buffer = md5.Hash;
        //        md5.Clear();
        //        return BitConverter.ToString(buffer).Replace("-", "-");
        //    }
        //}

        public static string Md5File(string fileName)
        {
            using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                if (fs.Length == 0)
                {
                    return Guid.NewGuid().ToString().Replace("-", "");
                }
                long bufferSize = 1024 * 1024 * 1024; // 1MB
                var buffer = new byte[bufferSize];

                var md5 = MD5.Create();
                md5.Initialize();

                var offset = 0L;
                while (offset < fs.Length)
                {
                    var readSize = bufferSize;
                    if (offset + readSize > fs.Length)
                    {
                        readSize = fs.Length - offset;
                    }

                    fs.Read(buffer, 0, (int)readSize);
                    if (offset + readSize < fs.Length)
                    {
                        // 非最后
                        md5.TransformBlock(buffer, 0, (int)readSize, buffer, 0);
                    }
                    else
                    {
                        md5.TransformFinalBlock(buffer, 0, (int)readSize);
                    }

                    offset += bufferSize;
                }

                var res = md5.Hash;
                md5.Clear();
                return BitConverter.ToString(res).Replace("-", "");
            }
        }
    }
}
